<?php
/**
 *　AmfExt.php
 *　@package Classes
 */

class AmfExt {

	const AMF0 = 0;
	const AMF3 = 3;

	private static $services = array();

	public static function Gateway($servicePath, $amfVersion = null) {
		$stream = file_get_contents('php://input');
		$input = amf_deserialize($stream, $amfVersion);
		$responsePacket = self::Request($input, $servicePath, $amfVersion);
		$rawOutputData = amf_serialize($responsePacket);
        header('Content-Type: application/x-amf');
        echo $rawOutputData;
	}

	private static function Request($input, $servicePath, $amfVersion) {
		$responsePacket = array(
			'headers' => array(),
			'num_headers' => $input['num_headers'],
			'messages' => array(),
			'num_messages' => $input['num_messages'],
			'amfVersion' => is_null($amfVersion) ? $input['amfVersion'] : $amfVersion
			);
		for ($i = 0; $i < $input['num_messages']; ++$i) {
			$requestMessage = $input['messages'][$i];
			$responseMessage = array('targetUri' => $requestMessage['responseUri'], 'responseUri' => 'null');
			try {
				if (empty($requestMessage['targetUri'])) throw new Exception('targetUri is null');
				$targetUri = strtr($requestMessage['targetUri'], '.', '/');
				$split = explode('/', $targetUri);
				if (!isset($split[1])) throw new Exception('targetUri ' . $requestMessage['targetUri'] . ' invalid');
				$serviceName = $split[0];
				$methodName = $split[1];
				$loc = $servicePath . '/' . $serviceName . '.php';
				if (!isset(self::$services[$loc])) {
					if (!is_file($loc)) throw new Exception('file not found: ' . $loc);
					self::$services[$loc] = array();
					include_once $loc;
				}
				$className = $serviceName;
				$service =& self::$services[$loc];
				if (!isset($service[$className])) $service[$className] = new $className();
				$serviceObject = $service[$className];
				if (!method_exists($serviceObject, $methodName)) {
					throw new Exception('method ' . $methodName . ' not found on ' . $className . ' object');
				}
				$responseMessage['targetUri'] .= '/onResult';
				$responseMessage['data'] = call_user_func_array(array($serviceObject, $methodName), $requestMessage['data']);
			} catch (Exception $exception) {
				$responseMessage['targetUri'] .= '/onStatus';
				$responseMessage['data'] = null;
			}
			$responsePacket['messages'][$i] = $responseMessage;
		}
		return $responsePacket;
	}

}

